home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Source Code / C / Applications / Python 1.3.3 / Python 133 SRC / Demo / www / gopherlib.py < prev    next >
Text File  |  1996-03-12  |  3KB  |  154 lines

  1. # Gopher protocol interface
  2.  
  3. # Default selector, host and port
  4. DEF_SELECTOR = ''
  5. DEF_HOST     = 'gopher.micro.umn.edu'
  6. DEF_PORT     = 70
  7.  
  8. # Recognized file types (same names as in Gopher C source)
  9. A_FILE       = '0'
  10. A_DIRECTORY  = '1'
  11. A_CSO        = '2'
  12. A_ERROR      = '3'
  13. A_MACHEX     = '4'
  14. A_PCHEX      = '5'
  15. A_INDEX      = '7'
  16. A_TELNET     = '8'
  17. A_UNIXBIN    = '9'
  18. A_SOUND      = 's'
  19. A_EVENT      = 'e'
  20. A_CALENDAR   = 'c'
  21. A_HTML       = 'h'
  22. A_TN3270     = 'T'
  23. A_MIME       = 'M'
  24. A_IMAGE      = 'I'
  25. A_EOI        = '.'
  26.  
  27. # These are unofficial ones that I've encountered...
  28. a_WHOIS      = 'w'
  29. a_QUERY      = 'q'
  30. a_GIF        = 'g'
  31. a_BUT        = 'b' # What's this?
  32.  
  33.  
  34. # Dictionary mapping known file types to strings
  35. _type_to_name_map = { \
  36.     A_FILE: 'TEXT', \
  37.     A_DIRECTORY: 'DIR', \
  38.     A_CSO: 'CSO', \
  39.     A_ERROR: 'ERROR', \
  40.     A_MACHEX: 'BINHEX', \
  41.     A_PCHEX: 'DOS', \
  42.     A_INDEX: 'INDEX', \
  43.     A_TELNET: 'TELNET', \
  44.     A_UNIXBIN: 'BINARY', \
  45.     A_SOUND: 'SOUND', \
  46.     A_EVENT: 'EVENT', \
  47.     A_CALENDAR: 'CALENDAR', \
  48.     A_HTML: 'HTML', \
  49.     A_TN3270: 'TN3270', \
  50.     A_MIME: 'MIME', \
  51.     }
  52.  
  53. # Function mapping all file types to strings; unknown types become TYPE='x'
  54. def type_to_name(gtype):
  55.     if _type_to_name_map.has_key(gtype):
  56.         return _type_to_name_map[gtype]
  57.     return 'TYPE=' + `gtype`
  58.  
  59. # Names for characters and strings
  60. CRLF = '\r\n'
  61. TAB = '\t'
  62.  
  63. # Send a selector to a given host and port, return a file with the reply
  64. def send_selector(selector, host, port):
  65.     import socket
  66.     if not port:
  67.         port = DEF_PORT
  68.     elif type(port) == type(''):
  69.         import string
  70.         port = string.atoi(port)
  71.     s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  72.     s.connect((host, port))
  73.     s.send(selector + CRLF)
  74.     s.shutdown(1)
  75.     return s.makefile('r')
  76.  
  77. # The following functions interpret the data returned by the gopher
  78. # server according to the expected type, e.g. textfile or directory
  79.  
  80. # Get a directory in the form of a list of entries
  81. def get_directory(f):
  82.     import string
  83.     list = []
  84.     while 1:
  85.         line = f.readline()
  86.         if not line:
  87.             print '(Unexpected EOF from server)'
  88.             break
  89.         if line[-2:] == CRLF:
  90.             line = line[:-2]
  91.         elif line[-1:] in CRLF:
  92.             line = line[:-1]
  93.         if line == '.':
  94.             break
  95.         if not line:
  96.             print '(Empty line from server)'
  97.             continue
  98.         gtype = line[0]
  99.         parts = string.splitfields(line[1:], TAB)
  100.         if len(parts) < 4:
  101.             print '(Bad line from server:', `line`, ')'
  102.             continue
  103.         if len(parts) > 4:
  104.             print '(Extra info from server:', parts[4:], ')'
  105.         parts.insert(0, gtype)
  106.         list.append(parts)
  107.     return list
  108.  
  109. # Get a text file as a list of lines, with trailing CRLF stripped
  110. def get_textfile(f):
  111.     list = []
  112.     get_alt_textfile(f, list.append)
  113.     return list
  114.  
  115. # Get a text file and pass each line to a function, with trailing CRLF stripped
  116. def get_alt_textfile(f, func):
  117.     while 1:
  118.         line = f.readline()
  119.         if not line:
  120.             print '(Unexpected EOF from server)'
  121.             break
  122.         if line[-2:] == CRLF:
  123.             line = line[:-2]
  124.         elif line[-1:] in CRLF:
  125.             line = line[:-1]
  126.         if line == '.':
  127.             break
  128.         if line[:2] == '..':
  129.             line = line[1:]
  130.         func(line)
  131.  
  132. # Get a binary file as one solid data block
  133. def get_binary(f):
  134.     data = f.read()
  135.     return data
  136.  
  137. # Get a binary file and pass each block to a function
  138. def get_alt_binary(f, func, blocksize):
  139.     while 1:
  140.         data = f.read(blocksize)
  141.         if not data:
  142.             break
  143.         func(data)
  144.  
  145. # Trivial test program
  146. def test():
  147.     import sys
  148.     selector, host, port = sys.argv[1], sys.argv[2], sys.argv[3]
  149.     f = send_selector(selector, host, port)
  150.     list = get_directory(f)
  151.     f.close()
  152.     for item in list:
  153.         print item
  154.